import { EnumProperty, IBind } from "xcore/cmpnt";
import cmpntBar from "./bind.loader";
import _ from "lodash";

interface InputValues {
  [key: string]: any;
}

export interface IBindCmpnt {
  inputValues: InputValues;
  updateModel: (key: string, value: any) => void;
  getEles: (key: string, conf: IBind) => any[];
}
//忽略属性
const ignoreProps: string[] = ["valueKey", "category", "cmpnt","containers", "viewable", "id", "options"]; //"options"



export function bindCmpnt(inputValues: InputValues = {} as InputValues, updateModel: (key: string, value: any) => void = () => { }): IBindCmpnt {
  const instance: IBindCmpnt = {
    inputValues: inputValues,
    updateModel: updateModel,
    getEles: function (key: string, conf: IBind): any[] {
      if (!cmpntBar.designer) throw new Error("cmpntBar.designer is undefined");
      if (_.startsWith(key, "_")) {
        return [];
      }
      if (ignoreProps.includes(key)) return [];

      const that = this;
      const value = that.inputValues[key];

      // 自定义组件
      if (conf.customCmpnt && conf.customCmpnt[key]) {
        const cmpntName = conf.customCmpnt[key];
        const customCmpnt = cmpntBar.designer.find(cmpntName).clone();
        customCmpnt.events["change"] = function (newvalue: any) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [customCmpnt];
      }
      else if (["btn type", "ctl type", "type"].includes(_.lowerCase(key)) ||
        _.endsWith(_.lowerCase(key), "b type")) {
        const tpCmpnt = cmpntBar.designer.find("styleSelect").clone();
        tpCmpnt.events["change"] = function (newvalue: any) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [tpCmpnt];
      }
      else if (["btn size", "ctl size", "size"].includes(_.lowerCase(key))) {
        const sizeCmpnt = cmpntBar.designer.find("sizeSelect").clone();
        sizeCmpnt.events["change"] = function (newvalue: any) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [sizeCmpnt];
      }
      else if (_.endsWith(_.lowerCase(key), "fields")) {
        const showColorTagConf = conf.properties?.includes(EnumProperty.ColorTagConf)
        const showFormatConf = conf.properties?.includes(EnumProperty.FormatConf)
        if (!showColorTagConf && !showFormatConf) return []
        const fieldEditorCmpnt = cmpntBar.designer.find("fieldEditor").clone();
        fieldEditorCmpnt.props.modelValue = that.inputValues[key];
        fieldEditorCmpnt.props.showColorTagConf = showColorTagConf
        fieldEditorCmpnt.props.showFormatConf = showFormatConf
        fieldEditorCmpnt.events["change"] = function (newvalue: any) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [fieldEditorCmpnt];
      }
      else if (_.endsWith(_.lowerCase(key), "field id")) {
        const fieldCmpnt = cmpntBar.designer.find("field select").clone();
        fieldCmpnt.props.modelValue = that.inputValues[key];
        fieldCmpnt.props.tableId = that.inputValues.DbTable?.id;
        if (!fieldCmpnt.props.tableId) return [];
        fieldCmpnt.events["change"] = function (newvalue: any) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [fieldCmpnt];
      }

      else if (_.endsWith(_.lowerCase(key), "data dict")) {
        const optionCmpnt = cmpntBar.designer.find("dictSelect").clone();
        optionCmpnt.props.modelValue = that.inputValues[key];
        optionCmpnt.events["change"] = function (newvalue: any) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [optionCmpnt];
      } else if (_.endsWith(_.lowerCase(key), "children") ||
        _.endsWith(_.lowerCase(key), "cmpnts")) {
        const childrenCmpnt = cmpntBar.designer.find("cmpntSelect").clone();
        childrenCmpnt.props.modelValue = that.inputValues[key];
        childrenCmpnt.events["change"] = function (newvalue: any) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [childrenCmpnt];
      }

      else if (_.endsWith(_.lowerCase(key), "color")) {
        const colorCmpnt = cmpntBar.designer.find("colorSelect").clone();
        colorCmpnt.props.modelValue = that.inputValues[key];
        colorCmpnt.events["change"] = function (newvalue: any) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [colorCmpnt];
      } else if (_.endsWith(_.lowerCase(key), "icon")) {
        const iconCmpnt = cmpntBar.designer.find("iconSelect").clone();
        iconCmpnt.props.modelValue = that.inputValues[key];
        iconCmpnt.events["change"] = function (newvalue: any) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [iconCmpnt];
      } else if (_.endsWith(_.lowerCase(key), "theme")) {
        const themeCmpnt = cmpntBar.designer.find("themeSelect").clone();
        themeCmpnt.events["change"] = function (newvalue: any) {
          that.inputValues[key] = _.join(newvalue, ",");
          that.updateModel(key, that.inputValues[key]);
        };
        return [themeCmpnt];
      } else if (_.endsWith(_.lowerCase(key), "class")) {
        const classCmpnt = cmpntBar.designer.find("classSelect").clone();

        classCmpnt.props.modelValue = that.inputValues[key];
        if (conf.specialClassGroups && conf.specialClassGroups[key]) {
          classCmpnt.props._allowGroups = conf.specialClassGroups[key]
        } else {
          classCmpnt.props._allowGroups = conf.classGroups
        }
        classCmpnt.events["change"] = function (newvalue: any) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [classCmpnt];
      } else if (["image", "file", "url"].some(item => _.lowerCase(key).indexOf(item) > -1)) {
        const uploadCmpnt = cmpntBar.designer.find("upload").clone();
        uploadCmpnt.props.modelValue = that.inputValues[key];
        uploadCmpnt.props.image = _.lowerCase(key).indexOf("image") > -1
        uploadCmpnt.props.multiple = _.isArray(that.inputValues[key])
        uploadCmpnt.events["change"] = function (newvalue: any) {
          if (uploadCmpnt.props.multiple) {
            that.inputValues[key] = [...newvalue]
          } else {
            that.inputValues[key] = _.head(newvalue) || ""
          }
          that.updateModel(key, that.inputValues[key]);
        };
        return [uploadCmpnt];
      } else if (_.isBoolean(value)) {
        const switchCmpnt = cmpntBar.designer.find("switch").clone();
        switchCmpnt.props.modelValue = that.inputValues[key];
        switchCmpnt.events["change"] = function (newvalue: boolean) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [switchCmpnt];
      } else if (_.isNumber(value)) {
        const numCmpnt = cmpntBar.designer.find("number").clone();
        numCmpnt.props.modelValue = that.inputValues[key];
        if (!numCmpnt.props.class.includes("w-100"))
          numCmpnt.props.class.push("w-100")
        numCmpnt.events["change"] = function (newvalue: number) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [numCmpnt];
      } else if (_.isString(value)) {
        const inputCmpnt = cmpntBar.designer.find("input").clone();
        inputCmpnt.props.modelValue = that.inputValues[key];
        if (!inputCmpnt.props.class.includes("w-100"))
          inputCmpnt.props.class.push("w-100")
        inputCmpnt.events["change"] = function (newvalue: string) {
          that.inputValues[key] = newvalue;
          that.updateModel(key, that.inputValues[key]);
        };
        return [inputCmpnt];
      } else if (_.isArray(value)) {
        const inputCmpnt = cmpntBar.designer.find("input").clone();
        inputCmpnt.props.modelValue = _.join(that.inputValues[key], ",");
        if (!inputCmpnt.props.class.includes("w-100"))
          inputCmpnt.props.class.push("w-100")
        inputCmpnt.events["change"] = function (newvalue: string) {
          that.inputValues[key] = _.split(newvalue, ",");
          that.updateModel(key, that.inputValues[key]);
        };
        return [inputCmpnt];
      }
      return [];
    }
  };

  return instance;
}